/*---------------------------------------------------------------------*/
/* --- STC MCU Limited ------------------------------------------------*/
/* --- STC 1T Series MCU Demo Programme -------------------------------*/
/* --- Mobile: (86)13922805190 ----------------------------------------*/
/* --- Fax: 86-0513-55012956,55012947,55012969 ------------------------*/
/* --- Tel: 86-0513-55012928,55012929,55012966 ------------------------*/
/* --- Web: www.STCMCU.com --------------------------------------------*/
/* --- Web: www.STCMCUDATA.com  ---------------------------------------*/
/* --- QQ:  800003751 -------------------------------------------------*/
/* ���Ҫ�ڳ�����ʹ�ô˴���,���ڳ�����ע��ʹ����STC�����ϼ�����            */
/*---------------------------------------------------------------------*/

#include "UART.h"
#include "MainTask.h"

#ifdef UART1
COMx_Define xdata COM1;
u8 xdata TX1_Buffer[COM_TX1_Lenth]; //���ͻ���
u8 xdata RX1_Buffer[COM_RX1_Lenth]; //���ջ���
#endif
#ifdef UART2
COMx_Define xdata COM2;
u8 xdata TX2_Buffer[COM_TX2_Lenth]; //���ͻ���
u8 xdata RX2_Buffer[COM_RX2_Lenth]; //���ջ���
#endif
#ifdef UART3
COMx_Define COM3;
u8 xdata TX3_Buffer[COM_TX3_Lenth]; //���ͻ���
u8 xdata RX3_Buffer[COM_RX3_Lenth]; //���ջ���
#endif
#ifdef UART4
COMx_Define COM4;
u8 xdata TX4_Buffer[COM_TX4_Lenth]; //���ͻ���
u8 xdata RX4_Buffer[COM_RX4_Lenth]; //���ջ���
#endif

u8 UART_Configuration(u8 UARTx, COMx_InitDefine *COMx)
{
	u8 i;
	u32 j;

#ifdef UART1
	if (UARTx == UART1)
	{
		COM1.id = 1;
		COM1.TX_read = 0;
		COM1.TX_write = 0;
		COM1.B_TX_busy = 0;
		COM1.RX_Cnt = 0;
		COM1.RX_TimeOut = 0;
		COM1.B_RX_OK = 0;
		for (i = 0; i < COM_TX1_Lenth; i++)
			TX1_Buffer[i] = 0;
		for (i = 0; i < COM_RX1_Lenth; i++)
			RX1_Buffer[i] = 0;

		if (COMx->UART_Polity > Polity_3)
			return 2;					 //����
		UART1_Polity(COMx->UART_Polity); //ָ���ж����ȼ�(�͵���) Polity_0,Polity_1,Polity_2,Polity_3
		if (COMx->UART_Mode > UART_9bit_BRTx)
			return 2; //ģʽ����
		SCON = (SCON & 0x3f) | COMx->UART_Mode;
		if ((COMx->UART_Mode == UART_9bit_BRTx) || (COMx->UART_Mode == UART_8bit_BRTx)) //�ɱ䲨����
		{
			j = (MAIN_Fosc / 4) / COMx->UART_BaudRate; //��1T����
			if (j >= 65536UL)
				return 2; //����
			j = 65536UL - j;
			if (COMx->UART_BRT_Use == BRT_Timer1)
			{
				TR1 = 0;
				AUXR &= ~0x01;	   //S1 BRT Use Timer1;
				TMOD &= ~(1 << 6); //Timer1 set As Timer
				TMOD &= ~0x30;	   //Timer1_16bitAutoReload;
				AUXR |= (1 << 6);  //Timer1 set as 1T mode
				TH1 = (u8)(j >> 8);
				TL1 = (u8)j;
				ET1 = 0;		   //��ֹ�ж�
				TMOD &= ~0x40;	   //��ʱ
				INT_CLKO &= ~0x02; //�����ʱ��
				TR1 = 1;
			}
			else if (COMx->UART_BRT_Use == BRT_Timer2)
			{
				AUXR &= ~(1 << 4); //Timer stop
				AUXR |= 0x01;	   //S1 BRT Use Timer2;
				AUXR &= ~(1 << 3); //Timer2 set As Timer
				AUXR |= (1 << 2);  //Timer2 set as 1T mode
				TH2 = (u8)(j >> 8);
				TL2 = (u8)j;
				IE2 &= ~(1 << 2); //��ֹ�ж�
				AUXR |= (1 << 4); //Timer run enable
			}
			else
				return 2; //����
		}
		else if (COMx->UART_Mode == UART_ShiftRight)
		{
			if (COMx->BaudRateDouble == ENABLE)
				AUXR |= (1 << 5); //�̶�������SysClk/2
			else
				AUXR &= ~(1 << 5); //�̶�������SysClk/12
		}
		else if (COMx->UART_Mode == UART_9bit) //�̶�������SysClk*2^SMOD/64
		{
			if (COMx->BaudRateDouble == ENABLE)
				PCON |= (1 << 7); //�̶�������SysClk/32
			else
				PCON &= ~(1 << 7); //�̶�������SysClk/64
		}
		if (COMx->UART_Interrupt == ENABLE)
			ES = 1; //�����ж�
		else
			ES = 0; //��ֹ�ж�
		if (COMx->UART_RxEnable == ENABLE)
			REN = 1; //��������
		else
			REN = 0;									   //��ֹ����
		P_SW1 = (P_SW1 & 0x3f) | (COMx->UART_P_SW & 0xc0); //�л�IO
		return 0;
	}
#endif
#ifdef UART2
	if (UARTx == UART2)
	{
		COM2.id = 2;
		COM2.TX_read = 0;
		COM2.TX_write = 0;
		COM2.B_TX_busy = 0;
		COM2.RX_Cnt = 0;
		COM2.RX_TimeOut = 0;
		COM2.B_RX_OK = 0;
		for (i = 0; i < COM_TX2_Lenth; i++)
			TX2_Buffer[i] = 0;
		for (i = 0; i < COM_RX2_Lenth; i++)
			RX2_Buffer[i] = 0;

		if ((COMx->UART_Mode == UART_9bit_BRTx) || (COMx->UART_Mode == UART_8bit_BRTx)) //�ɱ䲨����
		{
			if (COMx->UART_Polity > Polity_3)
				return 2;					 //����
			UART2_Polity(COMx->UART_Polity); //ָ���ж����ȼ�(�͵���) Polity_0,Polity_1,Polity_2,Polity_3
			if (COMx->UART_Mode == UART_9bit_BRTx)
				S2CON |= (1 << 7); //9bit
			else
				S2CON &= ~(1 << 7);					   //8bit
			j = (MAIN_Fosc / 4) / COMx->UART_BaudRate; //��1T����
			if (j >= 65536UL)
				return 2; //����
			j = 65536UL - j;
			AUXR &= ~(1 << 4); //Timer stop
			AUXR &= ~(1 << 3); //Timer2 set As Timer
			AUXR |= (1 << 2);  //Timer2 set as 1T mode
			TH2 = (u8)(j >> 8);
			TL2 = (u8)j;
			IE2 &= ~(1 << 2); //��ֹ�ж�
			AUXR |= (1 << 4); //Timer run enable
		}
		else
			return 2; //ģʽ����
		if (COMx->UART_Interrupt == ENABLE)
			IE2 |= 1; //�����ж�
		else
			IE2 &= ~1; //��ֹ�ж�
		if (COMx->UART_RxEnable == ENABLE)
			S2CON |= (1 << 4); //��������
		else
			S2CON &= ~(1 << 4);							 //��ֹ����
		P_SW2 = (P_SW2 & ~1) | (COMx->UART_P_SW & 0x01); //�л�IO
		return 0;
	}
#endif
#ifdef UART3
	if (UARTx == UART3)
	{
		COM3.id = 3;
		COM3.TX_read = 0;
		COM3.TX_write = 0;
		COM3.B_TX_busy = 0;
		COM3.RX_Cnt = 0;
		COM3.RX_TimeOut = 0;
		COM3.B_RX_OK = 0;
		for (i = 0; i < COM_TX1_Lenth; i++)
			TX3_Buffer[i] = 0;
		for (i = 0; i < COM_RX1_Lenth; i++)
			RX3_Buffer[i] = 0;

		if ((COMx->UART_Mode == UART_9bit_BRTx) || (COMx->UART_Mode == UART_8bit_BRTx)) //�ɱ䲨����
		{
			if (COMx->UART_Polity > Polity_3)
				return 2;					 //����
			UART3_Polity(COMx->UART_Polity); //ָ���ж����ȼ�(�͵���) Polity_0,Polity_1,Polity_2,Polity_3
			if (COMx->UART_Mode == UART_9bit_BRTx)
				S3_9bit(); //9bit
			else
				S3_8bit();							   //8bit
			j = (MAIN_Fosc / 4) / COMx->UART_BaudRate; //��1T����
			if (j >= 65536UL)
				return 2; //����
			j = 65536UL - j;
			if (COMx->UART_BRT_Use == BRT_Timer3)
			{
				S3_BRT_UseTimer3(); //S3 BRT Use Timer3;
				TH3 = (u8)(j >> 8);
				TL3 = (u8)j;
				T4T3M = 0x0a; //Timer3 set As Timer, 1T mode, Start timer3
			}
			else if (COMx->UART_BRT_Use == BRT_Timer2)
			{
				AUXR &= ~(1 << 4);	//Timer stop
				S3_BRT_UseTimer2(); //S3 BRT Use Timer2;
				AUXR &= ~(1 << 3);	//Timer2 set As Timer
				AUXR |= (1 << 2);	//Timer2 set as 1T mode
				TH2 = (u8)(j >> 8);
				TL2 = (u8)j;
				IE2 &= ~(1 << 2); //��ֹ�ж�
				AUXR |= (1 << 4); //Timer run enable
			}
			else
				return 2; //����
		}
		else
			return 2; //ģʽ����
		if (COMx->UART_Interrupt == ENABLE)
			S3_Int_Enable(); //�����ж�
		else
			S3_Int_Disable(); //��ֹ�ж�
		if (COMx->UART_RxEnable == ENABLE)
			S3_RX_Enable(); //��������
		else
			S3_RX_Disable();							 //��ֹ����
		P_SW2 = (P_SW2 & ~2) | (COMx->UART_P_SW & 0x02); //�л�IO
		return 0;
	}
#endif
#ifdef UART4
	if (UARTx == UART4)
	{
		COM4.id = 3;
		COM4.TX_read = 0;
		COM4.TX_write = 0;
		COM4.B_TX_busy = 0;
		COM4.RX_Cnt = 0;
		COM4.RX_TimeOut = 0;
		COM4.B_RX_OK = 0;
		for (i = 0; i < COM_TX1_Lenth; i++)
			TX4_Buffer[i] = 0;
		for (i = 0; i < COM_RX1_Lenth; i++)
			RX4_Buffer[i] = 0;

		if ((COMx->UART_Mode == UART_9bit_BRTx) || (COMx->UART_Mode == UART_8bit_BRTx)) //�ɱ䲨����
		{
			if (COMx->UART_Polity > Polity_3)
				return 2;					 //����
			UART4_Polity(COMx->UART_Polity); //ָ���ж����ȼ�(�͵���) Polity_0,Polity_1,Polity_2,Polity_3
			if (COMx->UART_Mode == UART_9bit_BRTx)
				S4_9bit(); //9bit
			else
				S4_8bit();							   //8bit
			j = (MAIN_Fosc / 4) / COMx->UART_BaudRate; //��1T����
			if (j >= 65536UL)
				return 2; //����
			j = 65536UL - j;
			if (COMx->UART_BRT_Use == BRT_Timer4)
			{
				S4_BRT_UseTimer4(); //S4 BRT Use Timer4;
				TH4 = (u8)(j >> 8);
				TL4 = (u8)j;
				T4T3M = 0xa0; //Timer4 set As Timer, 1T mode, Start timer4
			}
			else if (COMx->UART_BRT_Use == BRT_Timer2)
			{
				AUXR &= ~(1 << 4);	//Timer stop
				S4_BRT_UseTimer2(); //S4 BRT Use Timer2;
				AUXR &= ~(1 << 3);	//Timer2 set As Timer
				AUXR |= (1 << 2);	//Timer2 set as 1T mode
				TH2 = (u8)(j >> 8);
				TL2 = (u8)j;
				IE2 &= ~(1 << 2); //��ֹ�ж�
				AUXR |= (1 << 4); //Timer run enable
			}
			else
				return 2; //����
		}
		else
			return 2; //ģʽ����
		if (COMx->UART_Interrupt == ENABLE)
			S4_Int_Enable(); //�����ж�
		else
			S4_Int_Disable(); //��ֹ�ж�
		if (COMx->UART_RxEnable == ENABLE)
			S4_RX_Enable(); //��������
		else
			S4_RX_Disable();							 //��ֹ����
		P_SW2 = (P_SW2 & ~4) | (COMx->UART_P_SW & 0x04); //�л�IO
		return 0;
	}
#endif
	return 2; //����
}

/*********************************************************/

/********************* UART1 ���� ************************/
#ifdef UART1
void TX1_write2buff(u8 dat) //д�뷢�ͻ��壬ָ��+1
{
	TX1_Buffer[COM1.TX_write] = dat; //װ���ͻ���
	if (++COM1.TX_write >= COM_TX1_Lenth)
		COM1.TX_write = 0;

	if (COM1.B_TX_busy == 0) //����
	{
		COM1.B_TX_busy = 1; //��־æ
		TI = 1;				//���������ж�
	}
}

void PrintString1(u8 *puts)
{
	for (; *puts != 0; puts++)
		TX1_write2buff(*puts); //����ֹͣ��0����
}



void UART1_int(void) interrupt UART1_VECTOR
{
	if (RI)
	{
		RI = 0;
		if (COM1.B_RX_OK == 0)
		{
			if (COM1.RX_Cnt >= COM_RX1_Lenth)
				COM1.RX_Cnt = 0;
			RX1_Buffer[COM1.RX_Cnt++] = SBUF;
			COM1.RX_TimeOut = TimeOutSet1;
		}
	}

	if (TI)
	{
		TI = 0;
		if (COM1.TX_read != COM1.TX_write)
		{
			SBUF = TX1_Buffer[COM1.TX_read];
			if (++COM1.TX_read >= COM_TX1_Lenth)
				COM1.TX_read = 0;
		}
		else
			COM1.B_TX_busy = 0;
	}
}
#endif

/********************* UART2 ���� ************************/
#ifdef UART2
void TX2_write2buff(u8 dat) //д�뷢�ͻ��壬ָ��+1
{
	TX2_Buffer[COM2.TX_write] = dat; //װ���ͻ���
	if (++COM2.TX_write >= COM_TX2_Lenth)
		COM2.TX_write = 0;

	if (COM2.B_TX_busy == 0) //����
	{
		COM2.B_TX_busy = 1; //��־æ
		SET_TI2();			//���������ж�
	}
}

void PrintString2(u8 *puts)
{
	for (; *puts != 0; puts++)
		TX2_write2buff(*puts); //����ֹͣ��0����
}

char putchar(char c)
{
	TX2_write2buff(c);
	return c;
}

void UART2_int(void) interrupt UART2_VECTOR
{
	EA = 0;
	if (RI2)
	{
		CLR_RI2();
		if (COM2.B_RX_OK == 0)
		{
			if (COM2.RX_Cnt >= COM_RX2_Lenth)
				COM2.RX_Cnt = 0;
			RX2_Buffer[COM2.RX_Cnt++] = S2BUF;
			if (COM2.RX_Cnt >= COM_RX2_Lenth)
				COM2.RX_Cnt = 0;
			COM2.RX_TimeOut = TimeOutSet2;
		}
	}

	if (TI2)
	{
		CLR_TI2();
		if (COM2.TX_read != COM2.TX_write)
		{
			RS485EN = 1;
			S2BUF = TX2_Buffer[COM2.TX_read];
			if (++COM2.TX_read >= COM_TX2_Lenth)
				COM2.TX_read = 0;
		}
		else
		{
			RS485EN = 0;
			COM2.B_TX_busy = 0;
		}
	}
	EA = 1;
}
#endif

/********************* UART3 ���� ************************/
#ifdef UART3
void TX3_write2buff(u8 dat) //д�뷢�ͻ��壬ָ��+1
{
	TX3_Buffer[COM3.TX_write] = dat; //װ���ͻ���
	if (++COM3.TX_write >= COM_TX3_Lenth)
		COM3.TX_write = 0;

	if (COM3.B_TX_busy == 0) //����
	{
		COM3.B_TX_busy = 1; //��־æ
		SET_TI3();			//���������ж�
	}
}

void PrintString3(u8 *puts)
{
	for (; *puts != 0; puts++)
		TX3_write2buff(*puts); //����ֹͣ��0����
}

void UART3_int(void) interrupt UART3_VECTOR
{
	if (RI3)
	{
		CLR_RI3();
		if (COM3.B_RX_OK == 0)
		{
			if (COM3.RX_Cnt >= COM_RX3_Lenth)
				COM3.RX_Cnt = 0;
			RX3_Buffer[COM3.RX_Cnt++] = S3BUF;
			COM3.RX_TimeOut = TimeOutSet3;
		}
	}

	if (TI3)
	{
		CLR_TI3();
		if (COM3.TX_read != COM3.TX_write)
		{
			S3BUF = TX3_Buffer[COM3.TX_read];
			if (++COM3.TX_read >= COM_TX3_Lenth)
				COM3.TX_read = 0;
		}
		else
			COM3.B_TX_busy = 0;
	}
}
#endif

/********************* UART4 ���� ************************/
#ifdef UART4
void TX4_write2buff(u8 dat) //д�뷢�ͻ��壬ָ��+1
{
	TX4_Buffer[COM4.TX_write] = dat; //װ���ͻ���
	if (++COM4.TX_write >= COM_TX4_Lenth)
		COM4.TX_write = 0;

	if (COM4.B_TX_busy == 0) //����
	{
		COM4.B_TX_busy = 1; //��־æ
		SET_TI4();			//���������ж�
	}
}

void PrintString4(u8 *puts)
{
	for (; *puts != 0; puts++)
		TX4_write2buff(*puts); //����ֹͣ��0����
}

void UART4_int(void) interrupt UART4_VECTOR
{
	if (RI4)
	{
		CLR_RI4();
		if (COM4.B_RX_OK == 0)
		{
			if (COM4.RX_Cnt >= COM_RX4_Lenth)
				COM4.RX_Cnt = 0;
			RX4_Buffer[COM4.RX_Cnt++] = S4BUF;
			COM4.RX_TimeOut = TimeOutSet4;
		}
	}

	if (TI4)
	{
		CLR_TI4();
		if (COM4.TX_read != COM4.TX_write)
		{
			S4BUF = TX4_Buffer[COM4.TX_read];
			if (++COM4.TX_read >= COM_TX4_Lenth)
				COM4.TX_read = 0;
		}
		else
			COM4.B_TX_busy = 0;
	}
}
#endif

/*********************************************************/
/*
void COMx_write2buff(COMx_Define *COMx, u8 dat)	//д�뷢�ͻ��壬ָ��+1
{
	if(COMx->id == 1)	TX1_write2buff(dat);
	if(COMx->id == 2)	TX2_write2buff(dat);
	if(COMx->id == 3)	TX3_write2buff(dat);
	if(COMx->id == 4)	TX4_write2buff(dat);
}

void PrintString(COMx_Define *COMx, u8 *puts)
{
    for (; *puts != 0;	puts++)  COMx_write2buff(COMx,*puts); 	//����ֹͣ��0����
}
*/
